package com.xuecheng.framework.exception;

import com.google.common.collect.ImmutableBiMap;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.framework.model.response.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author gongfeiyue
 * @date 2020/5/18 14:51
 * @Description  统一的异常捕获类
 */
@ControllerAdvice //表示是一个控制器增强类 只要是用了@ExceptionHandler(class) 就是捕获class抛出的异常
public class ExceptionCatch {

  public final static Logger LOGGER = LoggerFactory.getLogger(ExceptionCast.class);

  //定义一个map，配置异常类型所对应的错误代码(线程安全)
  // 优点:使用EXCEPTIONS存放异常类型和错误代码的映射，ImmutableMap的特点：一旦创建不可改变，并且线程安全
  private static ImmutableBiMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;

  //定义map的builder对象，用来构建map的 使用builder来构建一个异常类型和错误代码的异常
  protected static ImmutableBiMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableBiMap.builder();

  static {  //在这里加入一些基础的异常类型判断
    //定义异常类型所对应的的错误代码  HttpMessageNotReadableException没有对参数进行json序列化
    builder.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM );
  }

  // A：捕获CustomException此类异常
  @ExceptionHandler(CustomException.class)
  @ResponseBody
  public ResponseResult customException(CustomException customException){
    // 记录日志
    LOGGER.error("catch exception:{}",customException.getMessage());

    ResultCode resultCode = customException.getResultCode();
    return new ResponseResult(resultCode);
  }

  // B：捕获不可预知类异常  todo
  @ExceptionHandler(Exception.class)
  @ResponseBody
  public ResponseResult exception(Exception exception){

    LOGGER.error("catch exception:{}",exception.getMessage());

    if (EXCEPTIONS == null){
      EXCEPTIONS = builder.build(); //EXCEPTIONS构建成功
    }
    throw new RuntimeException(exception); // 抛出我们自定义的异常
//    ResultCode resultCode = EXCEPTIONS.get(exception.getClass());
//    if (resultCode != null){
//      return new ResponseResult(resultCode);
//    }else {
//      return new ResponseResult(CommonCode.SERVER_ERROR); //返回99999 抱歉，系统繁忙，请稍后重试！
//    }
  }


}
